#include "ControladorServidor.h"

#include <vector>
#include <stdexcept>
#include <glibmm/spawn.h>
#include <gtkmm/messagedialog.h>

#include "Socket.h"


ControladorServidor::ControladorServidor(Glib::RefPtr<Gtk::Builder> b, std::string nomMenu, Configuraciones** cfg, operacion op)
{
	Gtk::MenuItem* mi = 0;
	b->get_widget(nomMenu, mi);
	if (!mi) throw std::runtime_error("No se encontró "+nomMenu);

	// Segun la operacion es la señal que se conecta
	conectarSignal(mi, op);

	this->_ppConfig = cfg;
}


ControladorServidor::~ControladorServidor(){
}


void ControladorServidor::conectarSignal(Gtk::MenuItem* mi, operacion op){
	switch ( op ){
		case INICIAR:
			mi->signal_activate().connect( sigc::mem_fun(*this,
				&ControladorServidor::iniciarServidor) );
			break;

		case DETENER:
			mi->signal_activate().connect( sigc::mem_fun(*this,
				&ControladorServidor::detenerServidor) );
			break;

		case REINICIAR:
			mi->signal_activate().connect( sigc::mem_fun(*this,
				&ControladorServidor::resetServidor) );
			break;

		default:
			throw std::runtime_error("La operacion señalada no esta soportada");
	}
}


void ControladorServidor::iniciarServidor(){
	// Si no hay datos de configuraciones guardados se avisa al usuario
	if (*this->_ppConfig == NULL){

		Gtk::MessageDialog md("Error al tratar de iniciar el servidor");
		md.set_secondary_text("No hay ningun archivo de configuración cargado");

		md.run();

		return;
	}

	try {
		std::vector<std::string> vec;
		vec.push_back( (*this->_ppConfig)->nomServer );
		vec.push_back( (*this->_ppConfig)->getNombreArch() );

		Glib::spawn_async_with_pipes("", vec);

	} catch (Glib::SpawnError& se){
		Gtk::MessageDialog md("Error al tratar de iniciar el servidor");
		md.set_secondary_text(se.what());

		md.run();
	}
}


void ControladorServidor::detenerServidor(){
	// Si no hay datos de configuraciones guardados se avisa al usuario
	if (*this->_ppConfig == NULL){

		Gtk::MessageDialog md("Error al tratar de detener el servidor");
		md.set_secondary_text("No hay ningun puerto de control configurado");

		md.run();

		return;
	}

	try {
		// Recupera el puerto donde hay que enviar la señal
		unsigned short int puerto = (*this->_ppConfig)->nroPuertoCtrl;

		// El servidor siempre esta en la misma maquina (o deberia)
		ClientSocket cs("127.0.0.1", puerto);

		// "q" es la señal de apagado del servidor
		char q = 'q';
		cs.send(static_cast<void*>( &q ), sizeof(q));

		cs.close();

	} catch (SocketException& sex){
		// Si el servidor no esta corriendo el socket no se puede conectar y tira 
		// una excepcion, en cualquier caso hay que avisarle al usuario que hubo 
		// un error sin reventar todo el programa
		Gtk::MessageDialog md("Error al tratar de detener el servidor");
		md.set_secondary_text("No fue posible realizar la conexión");

		md.run();
	}
}


void ControladorServidor::resetServidor(){
	// Tienen que existir la config para saber el puerto de control
	if (*this->_ppConfig != NULL){

		detenerServidor();
		sleep(2);	// Da tiempo al servidor de apagarse (2 segs)
		iniciarServidor();

	} else {
		Gtk::MessageDialog md("Error al tratar de reiniciar el servidor");
		md.set_secondary_text("No se puede ejecutar la acción requerida");

		md.run();
	}
}


